#include "../../common.h"

//--------------------------------------------------------------------------------
//	initialize an anim asset
//--------------------------------------------------------------------------------
void *IAnim::AssetInit( IAssetFile *pi, const CMasterIndexEntry *pme, void *context )
{
	IAnim	*ret;

	ret = (IAnim*)pi->GetChunk(pme->nameHash,pme->primaryChunk);
	if( ret )
	{
		ret->pBones    = OffsetToPointer(ret->pBones,ret);
		ret->pFrames   = OffsetToPointer(ret->pFrames,ret);
		ret->pTriggers = OffsetToPointer(ret->pTriggers,ret);
	}
	return (void*)ret;
}

//--------------------------------------------------------------------------------
//	uninitialize an anim asset
//--------------------------------------------------------------------------------
void IAnim::AssetUninit( void *ptr, void *context )
{
}

//--------------------------------------------------------------------------------
//	fixup an asset
//--------------------------------------------------------------------------------
void IAnim::AssetFixup( CAssetFileMgr *pMgr, const IAssetFile *pFile, void *ptr, const CMasterIndexEntry *pEntry )
{
}

//--------------------------------------------------------------------------------
//	convert a frame number into an integer and a fractional frame
//--------------------------------------------------------------------------------
inline void	GetFrameNumber( float frame, u32 numFrames, u32 &intFrame, f32 &fracFrame )
{
	if( frame<0.0f )
	{
		intFrame = 0;
		fracFrame = frame = 0.0f;
	}
	else if( frame>numFrames-1 )
	{
		intFrame = numFrames-1;
		fracFrame = 0.0f;
	}
	else
	{
		intFrame = (u32)frame;
		fracFrame = frame - intFrame;
	}
}


//--------------------------------------------------------------------------------
//	uninitialize an anim asset
//--------------------------------------------------------------------------------
void IAnim::Animate( f32 frame, CAnimResult &result ) const
{
	u32				i;
	u32				intFrame;
	f32				fracFrame;
	SAnimBoneData	*pbones[2];
	SAnimFrameData	*pframe;
	CQuaternion			q[3];

	GetFrameNumber(frame,numFrames,intFrame,fracFrame);

	pframe    = &pFrames[intFrame];
	pbones[0] = &pBones[numBones*intFrame];

	if( fracFrame==0.0f )
	{
		for( i=0;i<numBones;i++ )
			result.quatList[i].UnCompress(pbones[0][i].quat);
		result.rootPos = pframe->rootpos;
	}
	else
	{
		pbones[1] = &pbones[0][numBones];
		for( i=0;i<numBones;i++ )
		{
			// get the resultant rotation
			q[0].UnCompress(pbones[0][i].quat);
			q[1].UnCompress(pbones[1][i].quat);
			result.quatList[i].FastSlerp(q[0],q[1],fracFrame);
		}
		result.rootPos.Lerp(pframe->rootpos,pframe[1].rootpos,fracFrame);
	}
}

